package model;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

import org.apache.log4j.Logger;

@Entity
public class Cliente {
	private static Logger logger = Logger.getLogger(Cliente.class);
	
	/* Atributos normais */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long cliente_id;

	private String nome4;

	private String cnpj_cpf;

	private String email;

	private Date dataDeNascimento;

	/* Atributos de relacionamento */
	@ManyToMany(cascade = { CascadeType.PERSIST })
	@JoinTable(name = "CLIENTEENDERECO", joinColumns = @JoinColumn(name = "cliente_id"), inverseJoinColumns = @JoinColumn(name = "endereco_id"))
	private Collection<Endereco> enderecos = new ArrayList<Endereco>();

	@ManyToMany(cascade = { CascadeType.PERSIST })
	@JoinTable(name = "CLIENTEITEM", joinColumns = @JoinColumn(name = "cliente_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
	private Collection<Item> items = new ArrayList<Item>();

	@ManyToMany(cascade = { CascadeType.PERSIST })
	@JoinTable(name = "CLIENTENOTAFISCAL", joinColumns = @JoinColumn(name = "cliente_id"), inverseJoinColumns = @JoinColumn(name = "notafiscal_id"))
	private Collection<NotaFiscal> notasfiscais = new ArrayList<NotaFiscal>();

	/* Construtor sem argumentos para o JPA */
	public Cliente() {
		/* Uma gambiarra oficial para descobrir quem chamou o construtor */
		try {
			throw new IllegalStateException();
		} catch (IllegalStateException e) {
			StackTraceElement[] stackTrace = e.getStackTrace();
			StackTraceElement stackTraceElement = stackTrace[1];
			if(stackTraceElement.getClassName().equals("sun.reflect.NativeConstructorAccessorImpl")){
				Cliente.logger.debug("JPA construindo um cliente");
			}else{
				Cliente.logger.info("Construindo um cliente");
			}
		}
	}

	/* RELACIONAMENTO COM NOTAFISCAL */
	public Collection<Endereco> getEnderecos() {
		return enderecos;
	}

	public void addEndereco(Endereco endereco) {
		this.enderecos.add(endereco);
	}

	/* RELACIONAMENTO COM ITEM */
	public Collection<Item> getItems() {
		return items;
	}

	public void addItem(Item item) {
		this.items.add(item);
	}

	/* RELACIONAMENTO COM NOTAFISCAL */
	public Collection<NotaFiscal> getNotasfiscais() {
		return notasfiscais;
	}

	public void addNotaFiscal(NotaFiscal notaFiscal) {
		this.notasfiscais.add(notaFiscal);
	}

	/* GETTERS E SETTERS */
	public Long getCliente_id() {
		return cliente_id;
	}

	public void setCliente_id(Long cliente_id) {
		this.cliente_id = cliente_id;
	}

	public String getCnpj_cpf() {
		return cnpj_cpf;
	}

	public void setCnpj_cpf(String cnpj_cpf) {
		this.cnpj_cpf = cnpj_cpf;
	}

	public Date getDataDeNascimento() {
		return dataDeNascimento;
	}

	public void setDataDeNascimento(Date date) {
		this.dataDeNascimento = date;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getNome4() {
		return nome4;
	}

	public void setNome4(String nome4) {
		this.nome4 = nome4;
	}

	/* Métodos reescritos */
	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result
				+ ((cliente_id == null) ? 0 : cliente_id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Cliente other = (Cliente) obj;
		if (cliente_id == null) {
			if (other.cliente_id != null)
				return false;
		} else if (!cliente_id.equals(other.cliente_id))
			return false;
		return true;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		builder.append("Nome: " + this.nome4 + "\n");
		builder.append("CPF: " + this.cnpj_cpf + "\n");
		builder.append("Data de nascimento: " + this.dataDeNascimento + "\n");
		builder.append("email: " + this.email);
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		return builder.toString();
	}
}
